            /*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.uca.dss.curso2011.grupo5;

import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.query.Predicate;
import java.util.Iterator;
import java.util.List;
import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import org.uca.dss.curso2011.grupo5.interfaz.InterfazCompras;

/**
 *
 * @author Luis
 */
public class ReservaViaje implements InterfazCompras
{
    private List<Trayecto> ltrayectos;

    /**
     *
     * @param ltrayectos_w lista de trayectos disponibles en la agencia
     * @throws IllegalArgumentException
     */
    public ReservaViaje(List<Trayecto> ltrayectos) throws IllegalArgumentException
    {
        Args.comprobarNulo(ltrayectos);

        this.ltrayectos = ltrayectos;
    }

   /**
     * Permite realizar una reserva del viaje     
     * @param origen ciudad de origen
     * @param destino ciudad de destino
     * @param fecha fecha del viaje
     * @param hora hora del viaje
     * @return La cadena que identifica a la reserva
     * @throws IllegalArgumentException
     * @throws RuntimeException
     */
    public String reservaAsiento(String origen, String destino, LocalDate fecha, LocalTime hora) throws IllegalArgumentException, RuntimeException
    {
        Args.comprobarCadena(origen);
        Args.comprobarCadena(destino);
        Args.comprobarNulo(fecha);
        Args.comprobarNulo(hora);

        Viaje viaje = new Viaje(fecha, origen, destino, ltrayectos);
        
        Boolean encontrado = false;
        Iterator<Trayecto> itTrayectos = viaje.getTrayectos();
        Horario h = null;

        while(itTrayectos.hasNext() && !encontrado)
        {
            Trayecto t = itTrayectos.next();
            h = t.encontrarHorario(hora);
            if(h != null)
            {
                encontrado = true;
            }
        }

        if(!encontrado)
        {
            throw new RuntimeException("ReservaViaje: No se encuentra el horario especificado.");
        }
        else
        {
            int asientosReservados = viaje.reservasRealizadas(origen,destino,fecha,hora);

            if((h.getNumAsientos() - asientosReservados) > 0)
            {
                ObjectContainer db = DBUtils.getDb();
                Reserva r = new Reserva(origen,destino,fecha,hora);
                db.store(r);
                db.commit();
                
                return r.getCodigoReserva();
            }
            else
            {
                throw new RuntimeException("ReservaViaje: No hay plazas disponibles para el horario especificado.");
            }
        }
    }

   /**
     * Cancela una reserva, dejando el asiento indicado libre     
     * @param codigoReserva cadena que identifica la reserva
     * @throws IllegalArgumentException
     * @throws RuntimeException
     */
    public void cancelaReserva(String codigoReserva) throws IllegalArgumentException, RuntimeException
    {
        Args.comprobarCadena(codigoReserva);

        ObjectContainer db = DBUtils.getDb();

        ObjectSet<Reserva> reservas = db.query(new Predicate<Reserva>() {
            @Override
            public boolean match(Reserva et) {
                return true;
            }

        });

        Boolean encontrado = false;
        Reserva r = null;

        while(reservas.hasNext() && !encontrado)
        {
            r = reservas.next();

            if(r.getCodigoReserva().equalsIgnoreCase(codigoReserva))
            {
                encontrado = true;
            }
        }

        if(encontrado)
        {
            db.delete(r);
            db.commit();
        }
        else
        {
            throw new RuntimeException("ReservaViaje: No existe la reserva especificada.");
        }
    }
    
    /**
     * Permite comprobar el número de asientos libres     
     * @param origen ciudad de origen
     * @param destino ciudad de destino
     * @param fecha fecha del viaje
     * @param hora hora del viaje
     * @return número de asientos libres (no reservados)
     * @throws IllegalArgumentException
     * @throws RuntimeException
     */
     public int asientosLibres(String origen, String destino, LocalDate fecha, LocalTime hora) throws IllegalArgumentException,RuntimeException
     {
        Args.comprobarCadena(origen);
        Args.comprobarCadena(destino);
        Args.comprobarNulo(fecha);
        Args.comprobarNulo(hora);

        Viaje v = new Viaje(fecha,origen,destino,ltrayectos);
        Boolean encontrado = false;
        Horario h = null;

        Iterator<Trayecto> iteradorTrayectos = v.getTrayectos();

        while(iteradorTrayectos.hasNext() && !encontrado)
        {
            h = iteradorTrayectos.next().encontrarHorario(hora);

            if(h != null)
            {
                encontrado = true;
            }
        }

        if(encontrado)
        {
            int asientosReservados = v.reservasRealizadas(origen, destino, fecha, hora);
            
            return (h.getNumAsientos() - asientosReservados);
         }
        else
        {
            throw new RuntimeException("ReservaViaje: No existe el horario especificado.");
         }
     }

   /**
     * @param origen ciudad de origen
     * @param destino ciudad de destino
     * @param fecha fecha del viaje
     * @param hora hora del viaje
     * @return El precio de una reserva del viaje
     * @throws IllegalArgumentException
     */
    public double getPrecio(String origen, String destino, LocalDate fecha, LocalTime hora) throws IllegalArgumentException
    {
        Args.comprobarCadena(origen);
        Args.comprobarCadena(destino);
        Args.comprobarNulo(fecha);
        Args.comprobarNulo(hora);
        
        Viaje v =  new Viaje(fecha, origen, destino, ltrayectos);
        
        return v.calcularPrecioViaje(hora);
    }
}
